﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace MCP.Data.Client.Message
{
    public class MessagePool : List<MessageBase>
    {
        #region Constructors

        internal MessagePool(IEnumerable<MessageBase> messages)
        {
            if (messages != null) this.AddRange(messages);
        }

        //private MessagePool(params MessageBase[] messages)
        //{
        //    this.Push(messages);
        //}

        internal MessagePool(IEnumerable<MessageBase> messages, Exception exception)
            : this(messages)
        {
            if (exception != null) this.AddErrorMessage(exception);
        }

        #endregion

        /// <summary>
        /// Adds ErrorMessage to MessagePool if there is no such message yet.
        /// </summary>
        /// <param name="exception">Exception to base on.</param>
        public void AddErrorMessage(Exception exception)
        {
            if (exception == null) return;
            
            // if MessagePool doesn't have ErrorMessage for exception - add it:
            if (this.GetErrorMessage(exception) == null)
            {
                this.Add(new ErrorMessage(exception));
            }
        }

        /// <summary>
        /// Gets ErrorMessage by Exception.
        /// </summary>
        /// <param name="exception">Exception to look for.</param>
        /// <returns>Error message with corresponding exception.</returns>
        private ErrorMessage GetErrorMessage(Exception exception)
        {
            if (exception == null) return null;

            var errorMessages = this.Where(m => m.IsErrorMessage()).Select(m => m as ErrorMessage).ToList();
            return errorMessages.FirstOrDefault(em => em.Exception == exception);
        }

        /// <summary>
        /// Creates new instance on MessagePool if MessageBase collection is not empty.
        /// </summary>
        /// <param name="messages">MessageBase collection.</param>
        /// <returns>MessagePool or null if MessageBase collection is empty.</returns>
        public static MessagePool Create(IEnumerable<MessageBase> messages)
        {
            return MessagePool.Create(messages, null);
        }

        public static MessagePool Create(params MessageBase[] messages)
        {
            return MessagePool.Create(messages, null);
        }

        public static MessagePool Create(IEnumerable<MessageBase> messages, Exception exception)
        {
            if ((messages == null || messages.Count() == 0) && exception == null)
            {
                return null;
            }
            else
            {
                return new MessagePool(messages, exception);
            }
        }
    }

    public static class ExtentionData
    {
        public static MessagePool Push(this MessagePool pool, params MessageBase[] messages)
        {
			// remove empty or null messages:
            var messagesList = messages.ToList();
            var remove = messagesList.RemoveAll(m => m == null || string.IsNullOrWhiteSpace(m.Text));

	        //messages.ToList().RemoveAll(m => m == null || string.IsNullOrWhiteSpace(m.Text));
            if (!messagesList.Any()) return pool;

			// now messages are not empty and doesn't contain null or no-text message. Push them to message pool:
			if (pool == null)
			{
                pool = new MessagePool(messagesList);
			}
			else
			{
                pool.AddRange(messagesList);
			}
            
            return pool;
        }
    }
}